/**
 使用
 let customView = DragAlertBtnView(buttonText:"长文本按钮", arrangement: .horizontal)

 let config1 = PopupButtonConfig(
     title: "编辑资料",
     image: UIImage.init(named: "home_huiqian_icon2"),
     backgroundColor: .clear,
     titleColor: CHColor.gray94()
 )
 
 let config2 = PopupButtonConfig(
     title: "编辑资料2",
     image: UIImage.init(named: "home_huiqian_icon2"),
     backgroundColor: .clear,
     titleColor: CHColor.gray94()
 )
 
 
 let config3 = PopupButtonConfig(
     title: "编辑",
     image: UIImage.init(named: "home_huiqian_icon2"),
     backgroundColor: .clear,
     titleColor: CHColor.gray94()
 )
 customView.popupButtons = [config1,config2,config3]
  
//        customView.isDraggable = false
       
       // 设置回调
 customView.setButtonAction(isHideAlert: false) { index in
     print("水平排列按钮 \(index) 被点击")
     customView.setButtonBackgroundImage(UIImage.init(named: "home_huiqian_icon2"))

 }
 
 customView.frame = CGRect(x: 50, y: 200, width: 80, height: 40)
 self.view.addSubview(customView)
 */
import UIKit

/// 弹窗按钮排列类型
public enum PopupButtonArrangement {
    case vertical   // 垂直排列
    case horizontal // 水平排列（图片在上，文字在下）
}

/// 按钮配置模型
public struct PopupButtonConfig {
    public let title: String?
    public let image: UIImage?
    public let backgroundColor: UIColor?
    public let titleColor: UIColor?

    public init(title: String? = nil, image: UIImage? = nil, backgroundColor: UIColor? = nil, titleColor: UIColor? = nil) {
        self.title = title
        self.image = image
        self.backgroundColor = backgroundColor
        self.titleColor = titleColor
    }
}

/// 点击回调类型
public typealias PopupButtonAction = (Int) -> Void
/// 自定义可拖拽弹窗组件
public class DragAlertBtnView: UIView {
    public var onDragEnd: ((CGPoint) -> Void)? //返回坐标中心点
    
    public var onDragEndLeftTopPoint: ((CGPoint) -> Void)? //左上点坐标
    public var onDragEndLeftBottomPoint: ((CGPoint) -> Void)? //左下点坐标
    // MARK: - 公开属性
    
    /// 按钮显示的文字
    public var buttonText: String = "拖拽我" {
        didSet {
            updateButtonText()
        }
    }
    
    /// 按钮背景色
    public var buttonBackgroundColor: UIColor = .systemBlue {
        didSet {
            backgroundColor = buttonBackgroundColor
        }
    }
    
    /// 弹窗背景色
    public var popupBackgroundColor: UIColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0) {
        didSet {
            updatePopupAppearance()
        }
    }
    
    /// 弹窗按钮配置数组
    public var popupButtons: [PopupButtonConfig] = [] {
        didSet {
            updatePopupButtons()
        }
    }
    
    /// 按钮排列方式
    public var buttonArrangement: PopupButtonArrangement = .vertical {
        didSet {
            updatePopupButtons()
        }
    }
    
    /// 点击回调
    public var buttonAction: PopupButtonAction?
    
    /// 弹窗圆角半径
    public var popupCornerRadius: CGFloat = 12 {
        didSet {
            updatePopupAppearance()
        }
    }
    
    /// 按钮圆角半径
    public var buttonCornerRadius: CGFloat = 12 {
        didSet {
            layer.cornerRadius = buttonCornerRadius
        }
    }
    
    /// 是否启用拖拽功能
    public var isDraggable: Bool = true {
        didSet {
            setupGestures()
        }
    }
    
    /// 水平排列时的按钮间距
    public var horizontalButtonSpacing: CGFloat = 12 {
        didSet {
            if isPopupShowing {
                updatePopupSize()
                updatePopupPosition()
            }
        }
    }
    
    /// 垂直排列时的按钮间距
    public var verticalButtonSpacing: CGFloat = 8 {
        didSet {
            if isPopupShowing {
                updatePopupSize()
                updatePopupPosition()
            }
        }
    }
    
    /// 按钮背景图片
       public var buttonBackgroundImage: UIImage? {
           didSet {
               updateButtonAppearance()
           }
       }
    
    
    // MARK: - 私有属性
    private var popupView: UIView?
    private var isPopupShowing = false
    private var containerView: UIView?
    private var shapeLayer: CAShapeLayer?
    private let buttonLabel = UILabel()
    private var popupButtonViews: [UIButton] = []
    private var panGesture: UIPanGestureRecognizer?
    private let backgroundImageView = UIImageView() // 新增：背景图片视图
    // MARK: - 初始化方法
    
    /// 使用 frame 初始化
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
        setupGestures()
    }
    
    /// 使用 coder 初始化
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
        setupGestures()
    }
    
    /// 便捷初始化方法
    /// - Parameters:
    ///   - buttonText: 按钮文字
    ///   - buttonColor: 按钮颜色
    ///   - popupButtons: 弹窗按钮配置
    ///   - arrangement: 按钮排列方式
    // MARK: - 初始化方法
     public convenience init(buttonText: String,
                            buttonColor: UIColor = .systemBlue,
                            buttonBackgroundImage: UIImage? = nil, // 新增参数
                            popupButtons: [PopupButtonConfig] = [],
                            arrangement: PopupButtonArrangement = .vertical) {
         self.init(frame: .zero)
         self.buttonText = buttonText
         self.buttonBackgroundColor = buttonColor
         self.buttonBackgroundImage = buttonBackgroundImage // 设置背景图片
         self.popupButtons = popupButtons
         self.buttonArrangement = arrangement
         setupView()
         setupGestures()
     }
    
    // MARK: - 公开方法
    /// 设置按钮背景图片
      /// - Parameter image: 背景图片
      public func setButtonBackgroundImage(_ image: UIImage?) {
          buttonBackgroundImage = image
          updateButtonAppearance()
      }
    /// 显示弹窗
    public func showPopup() {
        guard let superview = superview, !popupButtons.isEmpty else { return }
        
        if isPopupShowing {
            hidePopup()
        } else {
            createPopupView()
            updatePopupPosition()
            
            if let containerView = containerView, let shapeLayer = shapeLayer {
                updatePopupShape(containerView: containerView, shapeLayer: shapeLayer)
            }
            
            popupView?.alpha = 0
            popupView?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
            
            UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .curveEaseInOut) {
                self.popupView?.alpha = 1
                self.popupView?.transform = CGAffineTransform.identity
            }
            
            isPopupShowing = true
        }
    }
    
    /// 隐藏弹窗
    public func hidePopup() {
        UIView.animate(withDuration: 0.2, animations: {
            self.popupView?.alpha = 0
            self.popupView?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        }) { _ in
            self.cleanupPopup()
        }
    }
    
    /// 更新按钮配置
    /// - Parameter configs: 新的按钮配置数组
    public func updateButtonConfigs(_ configs: [PopupButtonConfig]) {
        popupButtons = configs
    }
    
    private var isHideAlert:Bool = true
    /// 设置点击回调
    /// - Parameter action: 回调闭包
    public func setButtonAction(isHideAlert:Bool = true,_ action: @escaping PopupButtonAction) {
        buttonAction = action
        self.isHideAlert = isHideAlert
    }
    
    // MARK: - 布局
    public override var intrinsicContentSize: CGSize {
        let labelSize = buttonLabel.sizeThatFits(CGSize(width: 200, height: CGFloat.greatestFiniteMagnitude))
        return CGSize(width: labelSize.width + 24, height: labelSize.height + 16)
    }
    
    public override func layoutSubviews() {
        super.layoutSubviews()
        // 更新背景图片视图的frame
              backgroundImageView.frame = bounds
              if isPopupShowing {
                  updatePopupPosition()
              }
    }
}

// MARK: - 私有方法
private extension DragAlertBtnView {
    
    // MARK: - 设置视图
    func setupView() {
        backgroundColor = buttonBackgroundColor
        layer.cornerRadius = buttonCornerRadius
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowOpacity = 0.3
        layer.shadowRadius = 4
        
        buttonLabel.text = buttonText
        buttonLabel.textColor = .black
        buttonLabel.textAlignment = .center
        buttonLabel.font = UIFont.boldSystemFont(ofSize: 10)
        buttonLabel.numberOfLines = 0
        buttonLabel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(buttonLabel)
        
        // 设置背景图片视图
            backgroundImageView.contentMode = .scaleAspectFill
            backgroundImageView.clipsToBounds = true
            backgroundImageView.layer.cornerRadius = buttonCornerRadius
            addSubview(backgroundImageView)
        
        
        NSLayoutConstraint.activate([
            buttonLabel.topAnchor.constraint(equalTo: topAnchor, constant: 0),
            buttonLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0),
            buttonLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0),
            buttonLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0)
        ])
        
        updateButtonAppearance()
    }
    // MARK: - 更新按钮外观
     func updateButtonAppearance() {
         if let backgroundImage = buttonBackgroundImage {
             // 使用背景图片
             backgroundImageView.image = backgroundImage
             backgroundImageView.contentMode = .scaleAspectFill
             backgroundColor = .clear // 背景色设为透明
             buttonLabel.textColor = .black // 默认文字颜色为白色
         } else {
             // 使用背景色
             backgroundImageView.image = nil
             backgroundColor = buttonBackgroundColor
             buttonLabel.textColor = .black
         }
     }
    // MARK: - 手势设置
    func setupGestures() {
        // 移除现有手势
        gestureRecognizers?.forEach { removeGestureRecognizer($0) }
        
        // 点击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        addGestureRecognizer(tapGesture)
        
        // 拖拽手势
        if isDraggable {
            panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
            if let panGesture = panGesture {
                addGestureRecognizer(panGesture)
            }
        }
    }
    
    // MARK: - 事件处理
    @objc func handleTap() {
        showPopup()
    }
    
    @objc func handlePan(_ gesture: UIPanGestureRecognizer) {
        guard let superview = superview else { return }
        
        let translation = gesture.translation(in: superview)
        
        switch gesture.state {
        case .began, .changed:
            center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
            gesture.setTranslation(CGPoint.zero, in: superview)
            
            if isPopupShowing {
                updatePopupPosition()
            }
            
        case .ended, .cancelled:
            keepViewInBounds()
            
        default:
            break
        }
    }
    
    @objc func popupButtonTapped(_ sender: UIButton) {
        let index = sender.tag
        print("按钮被点击，索引: \(index)")
        buttonAction?(index)
        if self.isHideAlert == true{
           hidePopup()
        }

    }
    
    // MARK: - 更新方法
    func updateButtonText() {
        buttonLabel.text = buttonText
        invalidateIntrinsicContentSize()
    }
    
    func updatePopupAppearance() {
        if let shapeLayer = shapeLayer {
            shapeLayer.fillColor = popupBackgroundColor.cgColor
        }
    }
    
    func updatePopupButtons() {
        popupButtonViews.forEach { $0.removeFromSuperview() }
        popupButtonViews.removeAll()
        
        for (index, config) in popupButtons.enumerated() {
            let button = createButton(with: config, index: index)
            popupButtonViews.append(button)
        }
        
        if isPopupShowing {
            updatePopupSize()
            updatePopupPosition()
        }
    }
    
    func createButton(with config: PopupButtonConfig, index: Int) -> UIButton {
        let button = UIButton(type: .system)
        button.tag = index
        
        // 设置按钮背景色
        if let backgroundColor = config.backgroundColor {
            button.backgroundColor = backgroundColor
        } else {
            button.backgroundColor = .systemBlue
        }
        
        // 设置文字颜色
        if let titleColor = config.titleColor {
            button.setTitleColor(titleColor, for: .normal)
        } else {
            button.setTitleColor(.white, for: .normal)
        }
        
        // 设置标题
        button.setTitle(config.title, for: .normal)
        
        // 设置图片
        if let image = config.image {
            let originalImage = image.withRenderingMode(.alwaysOriginal)
            button.setImage(originalImage, for: .normal)
        }
        
        button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .medium)
        button.titleLabel?.textAlignment = .center
        button.layer.cornerRadius = 8
        
        // 添加点击事件
        button.addTarget(self, action: #selector(popupButtonTapped(_:)), for: .touchUpInside)
        
        // 根据排列方式设置按钮内容布局
        setupButtonContentLayout(button, config: config)
        
        return button
    }
    
    func setupButtonContentLayout(_ button: UIButton, config: PopupButtonConfig) {
            switch buttonArrangement {
            case .vertical:
                // 垂直排列：图片在左，文字在右
                if config.image != nil && config.title != nil {
                    button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -4, bottom: 0, right: 4)
                    button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: -4)
                    button.contentHorizontalAlignment = .left
                } else if config.image != nil {
                    button.contentHorizontalAlignment = .center
                } else if config.title != nil {
                    button.contentHorizontalAlignment = .center
                }
                
            case .horizontal:
                // 水平排列：图片在上，文字在下，间隔8
                if config.image != nil && config.title != nil {
                    // 图片在上，文字在下，间隔8
                    let imageTitleSpacing: CGFloat = 20
                    
                    // 调整图片位置：向上移动文字高度的一半 + 间距的一半
                    button.imageEdgeInsets = UIEdgeInsets(
                        top: 0,
                        left: 0,
                        bottom: imageTitleSpacing + (button.titleLabel?.font.lineHeight ?? 0) / 2,
                        right: -(button.titleLabel?.intrinsicContentSize.width ?? 0)
                    )
                    
                    // 调整文字位置：向下移动图片高度的一半 + 间距的一半
                    button.titleEdgeInsets = UIEdgeInsets(
                        top: imageTitleSpacing + (button.currentImage?.size.height ?? 0) / 2,
                        left: -(button.currentImage?.size.width ?? 0),
                        bottom: 0,
                        right: 0
                    )
                    
                    button.contentHorizontalAlignment = .center
                    button.contentVerticalAlignment = .center
                    
                } else if config.image != nil {
                    button.contentHorizontalAlignment = .center
                    button.contentVerticalAlignment = .center
                } else if config.title != nil {
                    button.contentHorizontalAlignment = .center
                    button.contentVerticalAlignment = .center
                }
            }
        }
    
    // MARK: - 弹窗管理
    func createPopupView() {
        guard let superview = superview else { return }
        
        cleanupPopup()
        
        popupView = UIView()
        popupView?.backgroundColor = .clear
        superview.addSubview(popupView!)
        
        containerView = UIView()
        containerView?.backgroundColor = .clear
        popupView?.addSubview(containerView!)
        
        shapeLayer = CAShapeLayer()
        shapeLayer?.shadowColor = UIColor.black.cgColor
        shapeLayer?.shadowOffset = CGSize(width: 0, height: 4)
        shapeLayer?.shadowOpacity = 0.2
        shapeLayer?.shadowRadius = 8
        
        containerView?.layer.addSublayer(shapeLayer!)
        
        // 重新创建按钮并添加到容器
        for button in popupButtonViews {
            containerView?.addSubview(button)
        }
        
        containerView?.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            containerView!.leadingAnchor.constraint(equalTo: popupView!.leadingAnchor),
            containerView!.trailingAnchor.constraint(equalTo: popupView!.trailingAnchor),
            containerView!.topAnchor.constraint(equalTo: popupView!.topAnchor),
            containerView!.bottomAnchor.constraint(equalTo: popupView!.bottomAnchor)
        ])
        
        setupButtonsLayout()
        updatePopupSize()
        
        popupView?.layoutIfNeeded()
        containerView?.layoutIfNeeded()
        
        // 确保按钮在容器的最上层
        if let containerView = containerView {
            for button in popupButtonViews {
                containerView.bringSubviewToFront(button)
            }
        }
    }
    
    func cleanupPopup() {
        popupView?.removeFromSuperview()
        popupView = nil
        containerView = nil
        shapeLayer = nil
        isPopupShowing = false
    }
    
    func setupButtonsLayout() {
        guard !popupButtonViews.isEmpty, let containerView = containerView else { return }
        
        for (index, button) in popupButtonViews.enumerated() {
            button.translatesAutoresizingMaskIntoConstraints = false
            
            switch buttonArrangement {
            case .vertical:
                setupVerticalLayout(for: button, at: index, in: containerView)
            case .horizontal:
                setupHorizontalLayout(for: button, at: index, in: containerView)
            }
        }
    }
    
    func setupVerticalLayout(for button: UIButton, at index: Int, in containerView: UIView) {
        if popupButtonViews.count == 1 {
            NSLayoutConstraint.activate([
                button.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 12),
                button.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 12),
                button.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -12),
                button.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20),
                button.heightAnchor.constraint(equalToConstant: 40)
            ])
        } else {
            NSLayoutConstraint.activate([
                button.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 12),
                button.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -12),
                button.heightAnchor.constraint(equalToConstant: 36)
            ])
            
            if index == 0 {
                button.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 12).isActive = true
            } else {
                button.topAnchor.constraint(equalTo: popupButtonViews[index - 1].bottomAnchor, constant: verticalButtonSpacing).isActive = true
            }
            
            if index == popupButtonViews.count - 1 {
                button.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20).isActive = true
            }
        }
    }
    
    func setupHorizontalLayout(for button: UIButton, at index: Int, in containerView: UIView) {
           // 水平排列时按钮尺寸
           let buttonWidth: CGFloat = 70  // 稍微增加宽度以适应文字
           let buttonHeight: CGFloat = 70 // 稍微增加高度以适应上下布局
           
           NSLayoutConstraint.activate([
               button.widthAnchor.constraint(equalToConstant: buttonWidth),
               button.heightAnchor.constraint(equalToConstant: buttonHeight),
               button.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 12)
           ])
           
           if index == 0 {
               button.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 12).isActive = true
           } else {
               button.leadingAnchor.constraint(equalTo: popupButtonViews[index - 1].trailingAnchor, constant: horizontalButtonSpacing).isActive = true
           }
           
           if index == popupButtonViews.count - 1 {
               button.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor, constant: -12).isActive = true
               button.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20).isActive = true
           }
       }
    
    func updatePopupSize() {
        guard let popupView = popupView else { return }
        
        let popupSize = calculatePopupSize()
        popupView.frame.size = popupSize
        
        if isPopupShowing {
            updatePopupPosition()
        }
    }
    
    func calculatePopupSize() -> CGSize {
        switch buttonArrangement {
        case .vertical:
            return calculateVerticalPopupSize()
        case .horizontal:
            return calculateHorizontalPopupSize()
        }
    }
    
    func calculateVerticalPopupSize() -> CGSize {
        let buttonCount = popupButtons.count
        let buttonHeight: CGFloat = buttonCount == 1 ? 40 : 36
        let buttonSpacing: CGFloat = buttonCount > 1 ? CGFloat(buttonCount - 1) * verticalButtonSpacing : 0
        let verticalPadding: CGFloat = 32
        let horizontalPadding: CGFloat = 24
        
        var maxButtonWidth: CGFloat = 120
        for button in popupButtonViews {
            let buttonSize = button.intrinsicContentSize
            maxButtonWidth = max(maxButtonWidth, buttonSize.width)
        }
        
        let popupWidth = min(250, maxButtonWidth + horizontalPadding)
        let popupHeight = CGFloat(buttonCount) * buttonHeight + buttonSpacing + verticalPadding
        
        return CGSize(width: popupWidth, height: popupHeight)
    }
    
    func calculateHorizontalPopupSize() -> CGSize {
           let buttonCount = popupButtons.count
           let buttonWidth: CGFloat = 70   // 调整宽度
           let buttonHeight: CGFloat = 70  // 调整高度
           let buttonSpacing: CGFloat = buttonCount > 1 ? CGFloat(buttonCount - 1) * horizontalButtonSpacing : 0
           let horizontalPadding: CGFloat = 24
           let verticalPadding: CGFloat = 32
           
           let popupWidth = CGFloat(buttonCount) * buttonWidth + buttonSpacing + horizontalPadding
           let popupHeight = buttonHeight + verticalPadding
           
           return CGSize(width: min(350, popupWidth), height: popupHeight) // 增加最大宽度限制
       }
    
    func updatePopupShape(containerView: UIView, shapeLayer: CAShapeLayer) {
        let path = UIBezierPath()
        let bounds = containerView.bounds
        let cornerRadius = popupCornerRadius
        let arrowWidth: CGFloat = 16
        let arrowHeight: CGFloat = 8
        
        path.move(to: CGPoint(x: cornerRadius, y: 0))
        path.addLine(to: CGPoint(x: bounds.width - cornerRadius, y: 0))
        path.addArc(withCenter: CGPoint(x: bounds.width - cornerRadius, y: cornerRadius),
                   radius: cornerRadius,
                   startAngle: -CGFloat.pi / 2,
                   endAngle: 0,
                   clockwise: true)
        path.addLine(to: CGPoint(x: bounds.width, y: bounds.height - arrowHeight - cornerRadius))
        path.addArc(withCenter: CGPoint(x: bounds.width - cornerRadius, y: bounds.height - arrowHeight - cornerRadius),
                   radius: cornerRadius,
                   startAngle: 0,
                   endAngle: CGFloat.pi / 2,
                   clockwise: true)
        
        let arrowCenterX = bounds.width / 2
        path.addLine(to: CGPoint(x: arrowCenterX + arrowWidth / 2, y: bounds.height - arrowHeight))
        path.addLine(to: CGPoint(x: arrowCenterX, y: bounds.height))
        path.addLine(to: CGPoint(x: arrowCenterX - arrowWidth / 2, y: bounds.height - arrowHeight))
        
        path.addLine(to: CGPoint(x: cornerRadius, y: bounds.height - arrowHeight))
        path.addArc(withCenter: CGPoint(x: cornerRadius, y: bounds.height - arrowHeight - cornerRadius),
                   radius: cornerRadius,
                   startAngle: CGFloat.pi / 2,
                   endAngle: CGFloat.pi,
                   clockwise: true)
        path.addLine(to: CGPoint(x: 0, y: cornerRadius))
        path.addArc(withCenter: CGPoint(x: cornerRadius, y: cornerRadius),
                   radius: cornerRadius,
                   startAngle: CGFloat.pi,
                   endAngle: -CGFloat.pi / 2,
                   clockwise: true)
        
        path.close()
        
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = popupBackgroundColor.cgColor
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.lineWidth = 0.5
    }
    
    func updatePopupPosition() {
        guard let popupView = popupView, let superview = superview else { return }
        
        let popupWidth = popupView.frame.width
        let popupHeight = popupView.frame.height
        let spacing: CGFloat = 2
        
        let popupY = frame.origin.y - popupHeight - spacing
        let popupX = center.x - popupWidth / 2
        
        var safeX = popupX
        var safeY = popupY
        
        if safeX < 8 {
            safeX = 8
        }
        
        if safeX + popupWidth > superview.bounds.width - 8 {
            safeX = superview.bounds.width - popupWidth - 8
        }
        
        if safeY < 8 {
            safeY = frame.origin.y + frame.height + spacing
            if isPopupShowing {
                hidePopup()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    self.showPopup()
                }
                return
            }
        }
        
        popupView.frame = CGRect(x: safeX, y: safeY, width: popupWidth, height: popupHeight)
        
        popupView.layoutIfNeeded()
        if let containerView = containerView, let shapeLayer = shapeLayer {
            updatePopupShape(containerView: containerView, shapeLayer: shapeLayer)
        }
    }
    
    func keepViewInBounds() {
        guard let superview = superview else { return }
        
        var newFrame = frame
        
        if newFrame.origin.x < 0 {
            newFrame.origin.x = 0
        }
        
        if newFrame.origin.x + newFrame.width > superview.bounds.width {
            newFrame.origin.x = superview.bounds.width - newFrame.width
        }
        
        if newFrame.origin.y < 0 {
            newFrame.origin.y = 0
        }
        
        if newFrame.origin.y + newFrame.height > superview.bounds.height {
            newFrame.origin.y = superview.bounds.height - newFrame.height
        }
        
        UIView.animate(withDuration: 0.2) {
            self.frame = newFrame
        }
        if self.onDragEnd != nil{
            self.onDragEnd!(CGPoint(x: newFrame.midX, y: newFrame.midY))
        }
        
        if self.onDragEndLeftTopPoint != nil{
            self.onDragEndLeftTopPoint!(CGPoint(x: newFrame.minX, y: newFrame.minY))
        }
        if self.onDragEndLeftBottomPoint != nil{
            self.onDragEndLeftBottomPoint!(CGPoint(x: newFrame.minX, y: newFrame.maxY))
        }
        
    }
}


